# coding=utf-8
from ..ToolsConfig import *
import random


def Probability(odds):
    """
    根据输入概率判断一次结果
    :param odds:概率float
    :return:bool
    """
    t = odds / 2.0
    d = random.uniform(t, 1.0 - t)
    return d - t < random.random() < d + t


class AddProbability(object):
    """
    累加概率算法，当进行到times次时，期望行动概率为100%，但并不代表本次判定为100%
    """

    def __init__(self, times):
        self.runTime = 0
        self.times = times
        self.k = 2.0 / times ** 2.0

    def ChanceOnce(self):
        """
        判断一次结果
        :return:bool
        """
        self.runTime += 1
        return Probability(self.runTime * self.k)


class AddProbabilityForMcServerTick(AddProbability):
    """
    针对MC系统的特殊算法
    status:R运行，S中止，F完成
    """

    def __init__(self, maxTime, system, func, *args):
        self.system = system
        super(AddProbabilityForMcServerTick, self).__init__(int(maxTime * 30.0))
        self.system.ListenForEvent(MC_SYSTEM_NAMESPACE, MC_SYSTEM_NAME, 'OnScriptTickServer', self, self.McTick)
        self.func = func
        self.funcParm = args
        self.status = 'R'

    def Suspend(self):
        """中止"""
        print "递增概率函数中止：{}".format(self.func.__name__)
        self.status = 'S'
        self.system.UnListenForEvent(MC_SYSTEM_NAMESPACE, MC_SYSTEM_NAME, 'OnScriptTickServer', self, self.McTick)

    def Start(self):
        """开始"""
        print "递增概率函数中止后再次开始：{}".format(self.func.__name__)
        self.status = 'R'
        self.system.ListenForEvent(MC_SYSTEM_NAMESPACE, MC_SYSTEM_NAME, 'OnScriptTickServer', self, self.McTick)

    def McTick(self):
        self.ChanceOnce()

    def ChanceOnce(self):
        """
        判断一次结果
        :return:bool
        """
        self.runTime += 1
        if Probability(self.runTime * self.k) or self.runTime >= self.times:
            self.system.UnListenForEvent(MC_SYSTEM_NAMESPACE, MC_SYSTEM_NAME, 'OnScriptTickServer', self, self.McTick)
            self.func(*self.funcParm)
            self.status = 'F'
            return True
        return False

    def Destroy(self):
        self.system.UnListenForEvent(MC_SYSTEM_NAMESPACE, MC_SYSTEM_NAME, 'OnScriptTickServer', self, self.McTick)
